
// import { useState } from "react"

// function DemoA(props) {
//   // 为什么这里使用const？
//   // 这了避免直接修改状态，要修改状态，有一个专属方法：setNum

//   // 为什么使用的是数组结构，不是对象解构？
//   // let obj = {name:"wc",age:18};  let {name,age} = obj;
//   // let arr = ["xq",18]; let [x,y] = arr;

//   // setNum是修改属性，有几种方式？
//   // 和setState不一样，它是没有第二个参数，callback
//   // 1)setNum(num+1)
//   // 2)setNum(_=>_+1)

//   // 调用setNum，组件的更新流程是什么样？
//   // 当调用setNum，会执行整个函数的重新执行，这个函数执行，生成一颗新的Fiber树，进一步进行协作运算，最后进行commit提交更新DOM。

//   // 整个函数重新执行，意味着：const [num, setNum] = useState(1) 这一行代码也会重新执行。
//   // 是不是就意味着，重新定义了一个状态1呢？
//   // 问：为什么可以实现加1？  答：调用setNum，整个函数确实会重新执行，按理说useState也会重新执行，num每一次都是1。但是使用use
//   // state定义状态时，定义出来的1是存储到reat最底层，当setNum执行时，并不会重新useState，而是使用你之前底层中定义的1

//   // setNum是同步还是异步?
//   // 在React18中，永远是异步的。
//   const [num, setNum] = useState(1)
//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA


// -----------------------------------------------------------


// import { useState, useEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)

//   // 这样写是没有依赖数组的
//   // 就意味着只要状态变化都会执行
//   useEffect(() => {
//     console.log("fn1...");
//     // ... 书写副作用（componentDidMount/componentDidUpdate）
//     return () => {
//       console.log("fn2...");
//       // ... 清除副作用（componentWillUnmount）
//     }
//   })
//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA


// -----------------------------------------------------------


// import { useState, useEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)

//   // 相当于写了componentDidMount
//   useEffect(() => {
//     console.log("fn1...");
//     return () => {
//       console.log("fn2...");
//     }
//   }, [])
//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import { useState, useEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)
//   const [counter, setCounter] = useState(1)

//   // 相当于写了componentDidMount
//   useEffect(() => {
//     console.log("fn1...");
//     return () => {
//       console.log("fn2...");
//     }
//   }, [num])
//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//       <hr />
//       <h2>函数式组件 -- {counter}</h2>
//       <button onClick={() => setCounter(counter + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import { useState, useEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)
//   const [counter, setCounter] = useState(1)

//   // 在vue3中有一个watchEffect，只不过vue3中的watchEffect是自动收集依赖

//   // 在react中需要我们手动收集依赖，react以后可能也会自动收集依赖
//   // 相当于写了componentDidMount
//   useEffect(() => {
//     console.log("fn1...");
//     return () => {
//       console.log("fn2...");
//     }
//   }, [num, counter])
//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//       <hr />
//       <h2>函数式组件 -- {counter}</h2>
//       <button onClick={() => setCounter(counter + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import { useState, useEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)
//   const [counter, setCounter] = useState(1)

//   useEffect(() => {
//     console.log("fn1...");
//     return () => {
//       console.log("fn2...");
//     }
//   }, [num, counter])

//   useEffect(() => {
//     console.log("发送ajax请求...", num);
//   }, [num])

//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//       <hr />
//       <h2>函数式组件 -- {counter}</h2>
//       <button onClick={() => setCounter(counter + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import { useState, useEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)

//   // useEffect(() => {
//   //   let t = setInterval(() => {
//   //     setNum(num + 1)
//   //   }, 1000)
//   //   return () => {
//   //     clearInterval(t)
//   //   }
//   // }, [num])

//   // let t = setInterval(() => {
//   //   setNum(num + 1)
//   // }, 1000)

//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import { useState, useEffect, useLayoutEffect } from "react"

// function DemoA(props) {
//   const [num, setNum] = useState(1)

//   useEffect(() => {
//     console.log("useEffect fn1...");
//     return () => {
//       console.log("useEffect fn2...");
//     }
//   }, [num])

//   // 类似于vue中beforecreate和created，在这里，是不能进行ref或dom操作
//   useLayoutEffect(() => {
//     console.log("useLayoutEffect fn1...");
//     return () => {
//       console.log("useLayoutEffect fn2...");
//     }
//   }, [num])

//   return (
//     <div>
//       <h2>函数式组件 -- {num}</h2>
//       <button onClick={() => setNum(num + 1)}>+1</button>
//     </div>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import { useState, useEffect, useLayoutEffect } from "react"
// const MlContext = React.createContext();
// const { Provider, Consumer } = MlContext;

// function Child(props) {
//   return (
//     <Consumer>
//       {
//         (ctx) => {
//           return (
//             <div>
//               <h2>函数式组件</h2>
//               <h3>{ctx}</h3>
//             </div>
//           )
//         }
//       }
//     </Consumer>
//   )
// }

// function DemoA(props) {
//   return (
//     <Provider value={"1000万"}>
//       <Child></Child>
//     </Provider>
//   )
// }

// export default DemoA
// -----------------------------------------------------------

// import { useState, useEffect, useLayoutEffect, useContext } from "react"
// const MlContext = React.createContext();
// const { Provider, Consumer } = MlContext;

// function Child(props) {
//   const ctx = useContext(MlContext)
//   return (
//     <div>
//       <h2>函数式组件</h2>
//       <h3>{ctx}</h3>
//     </div>
//   )
// }

// function DemoA(props) {
//   return (
//     <Provider value={"1000万"}>
//       <Child></Child>
//     </Provider>
//   )
// }

// export default DemoA

// -----------------------------------------------------------

// import React, { useState, useEffect, useLayoutEffect, useContext } from "react"

// class DemoA extends React.Component {
//   fn() {
//     let box = document.getElementById("box");
//     // console.log(box);
//     box.style.color = "red"
//   }
//   render() {
//     return (
//       <div>
//         <h1>类组件</h1>
//         <div id="box">我是一个div</div>
//         <button onClick={() => this.fn()}>点我</button>
//       </div>
//     )
//   }
// }

// export default DemoA

// -----------------------------------------------------------
// import React, { useState, useEffect, useLayoutEffect, useContext } from "react"

// class DemoA extends React.Component {
//   fn() {
//     console.log(this.refs.box);
//     this.refs.box.style.color = "blue";
//   }
//   render() {
//     return (
//       <div>
//         <h1>类组件</h1>
//         <div ref="box">我是一个div</div>
//         <button onClick={() => this.fn()}>点我</button>
//       </div>
//     )
//   }
// }

// export default DemoA

// -----------------------------------------------------------

// import React, { useState, useEffect, useLayoutEffect, useContext } from "react"

// class Child extends React.Component {
//   render() {
//     return (
//       <div>
//         子组件
//       </div>
//     )
//   }
// }

// class DemoA extends React.Component {
//   fn() {
//     console.log(this.refs.chi);
//   }
//   render() {
//     return (
//       <div>
//         <h1>类组件</h1>
//         {/* 如果ref写在组件标签上，是为了获取组件实例 */}
//         <Child ref="chi"></Child>
//         <button onClick={() => this.fn()}>点我</button>
//       </div>
//     )
//   }
// }

// export default DemoA

// -----------------------------------------------------------
// import React, { useState, useEffect, useLayoutEffect, useContext } from "react"

// function Child() {
//   return (
//     <div>
//       <button>我是Child组件中的button</button>
//       <h3>我是Child组件中的h3</h3>
//     </div>
//   )
// }


// React.forwardRef ref转发  可以获取函数式组件内部的标签了
// const Child = React.forwardRef((props, ref) => {
//   return (
//     <div>
//       <button>我是Child组件中的button</button>
//       <h3 ref={ref}>我是Child组件中的h3</h3>
//     </div>
//   )
// })

// class DemoA extends React.Component {
//   fn() {
//     console.log(this.refs.chi);
//   }
//   render() {
//     return (
//       <div>
//         <h1>类组件</h1>
//         {/* ref写在函数式组件的标签上，报错 */}
//         <Child ref="chi"></Child>
//         <button onClick={() => this.fn()}>点我</button>
//       </div>
//     )
//   }
// }

// export default DemoA

// -----------------------------------------------------------
// import React, { useState, useEffect, useLayoutEffect, useContext, useRef } from "react"

// const A = props => {
//   let box1 = useRef();
//   let box2 = useRef();
//   let fn = () => {
//     console.log(box1.current);
//     console.log(box2.current);
//   }
//   return (
//     <div>
//       <h2 ref={box1}>函数式组件</h2>
//       <h3 ref={box2}>我是一个h3</h3>
//       <button onClick={() => fn()}>点我</button>
//     </div>
//   )
// }


// export default () => {
//   return (
//     <A></A>
//   )
// }

// -----------------------------------------------------------

// import React, { useState, useEffect, useMemo, useLayoutEffect, useContext, useRef } from "react"

// const A = props => {
//   const [num, setNum] = useState(1)
//   const [count, setCount] = useState(1)

//   // 假定下面的是一个昂贵的计算
//   // useMemo 返回计算后的结果
//   // 下面这样写，相当于没有缓存，也就是每一次都会重新计算
//   let total = useMemo(() => {
//     console.log("昂贵的计算...");
//     return (1 + 2 + 3) * num;
//   }, [num])
//   return (
//     <div>
//       <h2>函数式组件</h2>
//       <h3>{total}</h3>
//       <button onClick={() => setNum(num + 1)}>setNum</button>
//       <button onClick={() => setCount(count + 1)}>setCount</button>
//     </div>
//   )
// }


// export default A;

// -----------------------------------------------------------

import React, { useState, useEffect, useCallback, useMemo, useLayoutEffect, useContext, useRef } from "react"

const A = props => {
  const [num, setNum] = useState(1)

  // 当我们调用了setNum，整个函数都要重新执行
  // 当重新执行时，看下面的代码
  // 函数是引用数据类型，是堆，fn函数都需要重新声明  
  // 可以使用useCallback把函数声明缓存起来
  let fn = useCallback(() => {

  // },[])  // [] 意味着这个函数只声明了一次  
  },[num])  // 当num变化了，需要重新声明此函数
  return (
    <div>
      <h2>函数式组件</h2>
      <button onClick={() => fn()}>setNum</button>
    </div>
  )
}


export default A;

// -----------------------------------------------------------

/*
下午安排：
  核心：总结React 
  总结如下内容：
    1）jsx 
    2）状态
    3）生命周期
    4）状态提升
    5）hooks (useState, useEffect)

  在gitee上创建一个仓库：
    把总结写到README.MD中，打开仓库，就可以直接看到总结
    或 
    写一片博客

  总结完后，看官方文档：

周六：
  1）如果没有总结完，继续总结
  2）背诵八股文
  3）提前预习一下，React项目，项目扔群中
*/
  























// -----------------------------------------------------------
// -----------------------------------------------------------
// -----------------------------------------------------------
// -----------------------------------------------------------
// -----------------------------------------------------------